package me.sealer.ssm.shiro.session;

import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.UnknownSessionException;
import org.apache.shiro.session.mgt.SessionContext;
import org.apache.shiro.session.mgt.SessionKey;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.apache.shiro.web.session.mgt.WebSessionKey;

import javax.servlet.ServletRequest;
import java.io.Serializable;

/**
 * @author sealer
 * @date 2018/05/18.
 */
@Slf4j
public class CustomWebSessionManager extends DefaultWebSessionManager {
    @Override
    protected Session doCreateSession(SessionContext context) {
        return super.doCreateSession(context);
    }

    @Override
    protected Session retrieveSession(SessionKey sessionKey) throws UnknownSessionException {
        Serializable sessionId = getSessionId(sessionKey);
        if (sessionId == null) {
            log.debug("Unable to resolve session ID from SessionKey [{}].  Returning null to indicate a " +
                    "session could not be found.", sessionKey);
            return null;
        }
        // 标志是否为WebSessionKey
        boolean isWebSessionKey = false;
        if (sessionKey instanceof WebSessionKey) {
            isWebSessionKey = true;
        }
        if (isWebSessionKey) {
            WebSessionKey webSessionKey = (WebSessionKey) sessionKey;
            ServletRequest request = webSessionKey.getServletRequest();
            Object sessionObject = request.getAttribute(sessionId.toString());
            if (sessionObject != null && sessionObject instanceof Session) {
                Session session = (Session) sessionObject;
                return session;
            }
        }

        Session s = retrieveSessionFromDataSource(sessionId);
        if (s == null) {
            //session ID was provided, meaning one is expected to be found, but we couldn't find one:
            String msg = "Could not find session with ID [" + sessionId + "]";
            throw new UnknownSessionException(msg);
        }

        if (isWebSessionKey) {
            WebSessionKey webSessionKey = (WebSessionKey) sessionKey;
            ServletRequest request = webSessionKey.getServletRequest();
            request.setAttribute(sessionId.toString(), s);
        }
        return s;
    }
}
